<?php

declare(strict_types=1);

namespace Smoren\Schemator\Tests\Unit\NestedAccessor;

use Smoren\Schemator\Components\NestedAccessor;

class NestedAccessorExistTest extends \Codeception\Test\Unit
{
    /**
     * @dataProvider dataProviderForExistTrueStrict
     * @dataProvider dataProviderForEqualNull
     */
    public function testExistTrueStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = isset($accessor[$path]);

        // Then
        $this->assertTrue($actual);
    }

    /**
     * @dataProvider dataProviderForExistTrueStrict
     */
    public function testIssetTrueStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->isset($path);

        // Then
        $this->assertTrue($actual);
    }

    /**
     * @dataProvider dataProviderForExistFalseStrict
     * @dataProvider dataProviderForExistTrueNonStrict
     * @dataProvider dataProviderForExistFalseNonStrict
     */
    public function testExistFalseStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = isset($accessor[$path]);

        // Then
        $this->assertFalse($actual);
    }

    /**
     * @dataProvider dataProviderForExistFalseStrict
     * @dataProvider dataProviderForExistTrueNonStrict
     * @dataProvider dataProviderForExistFalseNonStrict
     * @dataProvider dataProviderForEqualNull
     */
    public function testIssetFalseStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->isset($path);

        // Then
        $this->assertFalse($actual);
    }

    /**
     * @dataProvider dataProviderForExistTrueNonStrict
     * @dataProvider dataProviderForExistTrueStrict
     * @dataProvider dataProviderForEqualNull
     */
    public function testExistTrueNonStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->exist($path, false);

        // Then
        $this->assertTrue($actual);
    }

    /**
     * @dataProvider dataProviderForExistTrueNonStrict
     * @dataProvider dataProviderForExistTrueStrict
     */
    public function testIssetTrueNonStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->isset($path, false);

        // Then
        $this->assertTrue($actual);
    }

    /**
     * @dataProvider dataProviderForExistFalseNonStrict
     */
    public function testExistFalseNonStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->exist($path, false);

        // Then
        $this->assertFalse($actual);
    }

    /**
     * @dataProvider dataProviderForExistFalseNonStrict
     * @dataProvider dataProviderForEqualNull
     */
    public function testIssetFalseNonStrict($source, $path)
    {
        // Given
        $accessor = new NestedAccessor($source);

        // When
        $actual = $accessor->isset($path, false);

        // Then
        $this->assertFalse($actual);
    }

    public function dataProviderForExistTrueStrict(): array
    {
        return [
            [
                [],
                [],
            ],
            [
                [],
                null,
            ],
            [
                ['a' => 1],
                [],
            ],
            [
                [1, 2, 3],
                null,
            ],
            [
                [1, 2, 3],
                '*',
            ],
            [
                [1, 2, 3, 'a' => 4],
                '*',
            ],
            [
                [1, 2, 3, 'a' => 4],
                0,
            ],
            [
                [1, 2, 3, 'a' => 4],
                '0',
            ],
            [
                [1, 2, 3, 'a' => 4],
                '2',
            ],
            [
                [1, 2, 3, 'a' => 4],
                2,
            ],
            [
                [1, 2, 3, 'a' => 4],
                'a',
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'a' => 3]],
                'a',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 12], 'c' => [22, 23]]],
                'a.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 12], 'c' => [22, 23]]],
                'a.*.|.0',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'a.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 22], 'c' => [33, 44]]],
                'a.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 22], 'c' => [33, 44]]],
                'a.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 22], 'c' => [33, 44]]],
                'a.*.0',
            ],
            [
                [1, 2, 3, 'a' => [[11, 22], [33, 44]]],
                'a.*',
            ],
            [
                [1, 2, 3, 'a' => [[11, 22], [33, 44]]],
                'a.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.0',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.1',
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.b',
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.b.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => ['c', 'd', 'e'], [11, 22]]],
                'a.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [['c'], ['d'], ['e']], [[11], [22, 33]]]],
                'a.*.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [['c'], ['d'], ['e']], [[11], [22, 33]]]],
                'a.*.*.0',
            ],
            [
                [1, 2, 3, 'a' => ['b' => ['c', 'd', 'e'], [11, 22]]],
                ['a', '*', '*'],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                '*.0',
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                ['*', 0],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                ['*', '2'],
            ],
            [
                [
                    'a' => [1, 2, [3]],
                    'b' => [11, 22, [33]],
                    'c' => [111, 222, [333]],
                ],
                ['*', '2'],
            ],
            [
                [
                    'a' => [1, 2, [3]],
                    'b' => [11, 22, [33]],
                    'c' => [111, 222, [333]],
                ],
                ['*', '2', '*'],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                '*.*',
            ],
            [
                [
                    [
                        'a' => [1, 2, 3],
                        'b' => [11, 22, 33],
                        'c' => [111, 222, 333],
                    ],
                ],
                '*.*.0',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.*.0',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a.0',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a.*',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.b.|.1',
            ],
            [
                [
                    'first' => [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    'second' => [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                        ],
                    ],
                ],
                '*.*.*.1',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.*.0',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.0.0',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.0.*',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [2222],
                            ],
                        ],
                        [
                            [
                                [11111],
                                [222222],
                            ],
                        ],
                    ],
                ],
                'second.0.0.0',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.d',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.e',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.|.1.e',
            ],
        ];
    }

    public function dataProviderForExistFalseStrict(): array
    {
        return [
            [
                [],
                '*',
            ],
            [
                [],
                [''],
            ],
            [
                [],
                'test',
            ],
            [
                [],
                'foo.bar',
            ],
            [
                [],
                'foo.bar.*',
            ],
            [
                [],
                'foo.*.bar',
            ],
            [
                [1, 2, 3, 'a' => 4],
                3,
            ],
            [
                [1, 2, 3, 'a' => 4],
                'a.c',
            ],
            [
                [1, 2, 3, 'a' => 4],
                'a.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'a.*.1',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'a.*.a',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'a.*.test',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'a.*.*.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.1.0',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.2',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.*.a',
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.c',
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.c.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => ['c', 'd', 'e'], [11, 22]]],
                'a.*.x.*',
            ],
            [
                [1, 2, 3, 'a' => ['b' => [['c'], ['d'], ['e']], [[], [22, 33]]]],
                'a.*.*.0',
            ],
            [
                [1, 2, 3, 'a' => ['b' => ['c', 'd', 'e'], [11, 22]]],
                ['a', '*', 'y'],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11],
                    'c' => [111, 222, 333],
                ],
                '*.1',
            ],
            [
                [
                    'a' => [1],
                    'b' => [11, 22],
                    'c' => [111, 222, 333],
                ],
                ['*', 2],
            ],
            [
                [
                    'a' => [1, 2, [3]],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, [333]],
                ],
                ['*', '2', '*'],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => '[111, 222, 333]',
                ],
                '*.*',
            ],
            [
                [
                    [
                        'a' => [1, 2, 3],
                        'b' => '[11, 22, 33]',
                        'c' => [111, 222, 333],
                    ],
                ],
                '*.*.0',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.*.0',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a.2',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a.*.1',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.b.|.2',
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.b.|.1',
            ],
            [
                [
                    'first' => [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    'second' => [
                        [
                            'a' => [4],
                            'b' => [44, 55],
                        ],
                    ],
                ],
                '*.*.*.1',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [],
                            ],
                        ],
                    ],
                ],
                'second.*.*.*.0',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.0.*.0',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [],
                        ],
                    ],
                ],
                'second.*.*.0.*.*',
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [],
                            [
                                [1111],
                                [2222],
                            ],
                        ],
                        [
                            [
                                [11111],
                                [222222],
                            ],
                        ],
                    ],
                ],
                'second.0.0.0',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.d',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.e',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.|.1.e',
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.|.1.e',
            ],
        ];
    }

    public function dataProviderForExistTrueNonStrict(): array
    {
        return [
            [
                [1, 2, 3, 'a' => [
                    'b' => [['c'], ['d'], ['e']],
                    [[11], [22, 33]]],
                ],
                'a.*.*.1',
                [33],
            ],
            [
                [1, 2, 3, 'a' => [
                    'b' => [['c'], ['d'], ['e']],
                    [[11], [22, 33]]],
                ],
                'a.**.1',
                [33],
            ],
            [
                [
                    'a' => [1, 2],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                ['*', '2'],
                [33, 333],
            ],
            [
                [
                    'a' => [1, 2],
                    'b' => [11, 22, [33]],
                    'c' => [111, 222, [333]],
                ],
                ['*', '2'],
                [[33], [333]],
            ],
            [
                [
                    'a' => [1, 2, [3]],
                    'b' => [11, 22],
                    'c' => [111, 222, [333]],
                ],
                ['*', '2', '*'],
                [3, 333],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.a.2',
                [3],
            ],
            [
                [
                    'first' => [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    'second' => [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                        ],
                    ],
                ],
                '*.*.*.2',
                [3, 33, 333],
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.*.2',
                [3, 33, 333],
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111, 999],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.0.1',
                [2, 999],
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.2',
                [[111, 222, 333]],
            ],
            [
                [
                    'first' => [
                        [
                            [
                                'a' => [],
                                'b' => ['aaa'],
                                'c' => ['bbb'],
                            ],
                        ],
                    ],
                    'second' => [
                        [
                            [
                                [1, 2, 3],
                                [11, 22, 33],
                                [111, 222, 333],
                            ],
                            [
                                [1111],
                                [11111],
                            ],
                        ],
                        [
                            [
                                [111111],
                                [1111111],
                            ],
                        ],
                    ],
                ],
                'second.*.*.2.*',
                [111, 222, 333],
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.d',
                [1, 3],
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.e',
                [[4, 5, 6], [7, 8, 9]],
            ],
        ];
    }

    public function dataProviderForExistFalseNonStrict(): array
    {
        return [
            [
                [1, 2, 3, 'a' => 4],
                3,
                null,
            ],
            [
                [1, 2, 3, 'a' => 4],
                '3',
                null,
            ],
            [
                [1, 2, 3, 'a' => 4],
                'b',
                null,
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'a' => 3]],
                'b.*',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'b.*.0',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11], 'c' => [22]]],
                'b.*.*',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => [11, 22], 'c' => [33, 44]]],
                'b.*.*',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'b.*.0.0',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.2',
                [],
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.1.0',
                [],
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.111.1',
                [],
            ],
            [
                [1, 2, 3, 'a' => ['b' => [[11, 22]], 'c' => [[33, 44]]]],
                'a.*.0.*.111',
                [],
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.c',
                null,
            ],
            [
                [1, 2, 3, 'a' => [1, 2, 'b' => ['c', 'd', 'e']]],
                'a.c.*',
                null,
            ],
            [
                [1, 2, 3, 'a' => ['b' => ['c', 'd', 'e'], [11, 22]]],
                'a.*.e',
                [],
            ],
            [
                [1, 2, 3, 'a' => ['b' => [['c'], ['d'], ['e']], [[11], [22, 33]]]],
                'a.*.e.*',
                [],
            ],
            [
                [1, 2, 3, 'a' => [
                    'b' => [['c'], ['d'], ['e']],
                    [[11], [22, 33]]],
                ],
                'a.**.2',
                [],
            ],
            [
                [1, 2, 3, 'a' => [
                    'b' => [['c'], ['d'], ['e']],
                    [[11], [22, 33]]],
                ],
                'a.**.test',
                [],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                '*.3',
                [],
            ],
            [
                [
                    'a' => [1, 2, 3],
                    'b' => [11, 22, 33],
                    'c' => [111, 222, 333],
                ],
                ['*', 3],
                [],
            ],
            [
                [
                    [
                        'a' => [1, 2, 3],
                        'b' => [11, 22, 33],
                        'c' => [111, 222, 333],
                    ],
                ],
                '*.*.5',
                [],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.*.3',
                [],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.z',
                [],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.z.0',
                [],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.z.1',
                [],
            ],
            [
                [
                    [
                        [
                            'a' => [1, 2, 3],
                            'b' => [11, 22, 33],
                            'c' => [111, 222, 333],
                        ],
                    ],
                    [
                        [
                            'a' => [4, 5],
                            'b' => [44, 55],
                            'c' => [444, 555],
                        ],
                    ],
                ],
                '*.*.b.|.z',
                null,
            ],
            [
                [
                    'a' => [
                        [
                            'b' => [
                                [
                                    'c' => [
                                        [
                                            'd' => 1,
                                            'e' => [1, 2, 3],
                                        ]
                                    ],
                                    'f' => [
                                        [
                                            'd' => 2,
                                            'e' => [4, 5, 6],
                                        ]
                                    ],
                                ],
                            ],
                            'i' => [
                                [
                                    'j' => [
                                        [
                                            'd' => 3,
                                            'e' => [7, 8, 9],
                                        ]
                                    ]
                                ],
                            ],
                        ],
                    ],
                ],
                'a.*****.|.1.f',
                null,
            ],
        ];
    }

    public function dataProviderForEqualNull(): array
    {
        return [
            [
                null,
                [],
            ],
            [
                [null, 2, 3, 'a' => 4],
                0,
            ],
            [
                ['a' => null, 'b' => 1],
                'a',
            ],
            [
                [null, null],
                '1',
            ],
        ];
    }
}
